package com.yangcangclub.system.domain;

import com.yangcangclub.commons.exception.ApolloException;
import com.yangcangclub.commons.result.MessageEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * 图片验证码
 */
@Component
public class ImgValidateCode {

    @Autowired
    public RedisTemplate<Object,Object> redisTemplate;


    private static Random random = new Random();
    private static String randString = "23456789abcdefghijkmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ";//随机产生的字符串
    private static int lineSize = 40;//干扰线数量
    private static int stringNum = 4;//随机产生字符数量

    /**
     * 生成随机图片
     */
    public void getImgcode(HttpServletResponse response,String key,int width,int height)throws Exception {

            //BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类
            BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
            Graphics g = image.getGraphics();//产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作
            g.fillRect(0, 0, width, height);
            g.setFont(new Font("Times New Roman",Font.ROMAN_BASELINE,25));
            g.setColor(getRandColor(110, 133));
            //绘制干扰线
            for(int i=0;i<=lineSize;i++){
                drowLine(g,width,height);
            }
            //绘制随机字符
            String randomString = "";
            for(int i=1;i<=stringNum;i++){
                randomString=drowString(g,randomString,i);
            }
            //把随机字符存入缓存中
            redisTemplate.boundValueOps("system.imgcode."+key+".value").set(randomString,60*20, TimeUnit.SECONDS);

            g.dispose();
            ImageIO.write(image, "JPEG", response.getOutputStream());//将内存中的图片通过流动形式输出到客户端

    }



    /**
     * 校验图片验证码，不区分大小写
     */
    public boolean verifyImgcode(String key,String code){

        if(key==null||code==null){
            throw new ApolloException(MessageEnum.PARMA_IS_EMPTY);
        }

        Object obj=redisTemplate.boundValueOps("system.imgcode." + key + ".value").get();

        if(obj==null|| ! code.equalsIgnoreCase((String)obj)){
            return false;
        }else{
            return true;
        }

    }


    /**
     * 绘制字符串
     */
    private static String drowString(Graphics g,String randomString,int i){
        g.setFont(getFont());
        g.setColor(new Color(random.nextInt(101),random.nextInt(111),random.nextInt(121)));
        String rand = String.valueOf(getRandomString(random.nextInt(randString.length())));
        randomString +=rand;
        g.translate(random.nextInt(3), random.nextInt(3));
        g.drawString(rand, 13*i, 16);
        return randomString;
    }
    /**
     * 绘制干扰线
     */
    private static void drowLine(Graphics g,int width,int height ){
        int x = random.nextInt(width);
        int y = random.nextInt(height);
        int xl = random.nextInt(13);
        int yl = random.nextInt(15);
        g.drawLine(x, y, x+xl, y+yl);
    }
    /**
     * 获取随机的字符
     */
    private static String getRandomString(int num){
        return String.valueOf(randString.charAt(num));
    }
    /**
     * 获得字体
     */
    private static  Font getFont(){
        return new Font("Fixedsys",Font.CENTER_BASELINE,25);
    }
    /**
     * 获得颜色
     */
    private static Color getRandColor(int fc,int bc){
        if(fc > 255)
            fc = 255;
        if(bc > 255)
            bc = 255;
        int r = fc + random.nextInt(bc-fc-16);
        int g = fc + random.nextInt(bc-fc-14);
        int b = fc + random.nextInt(bc-fc-18);
        return new Color(r,g,b);
    }
}